package com.general.framework.cc.lock;

/**
 * 更好的做法是使用条件变量或信号量来控制访问共享资源。
 * 在 Java 中，java.util.concurrent.locks 包提供了 Lock 和 Condition 接口，可以实现更细粒度的锁和条件等待
 */
// 用wait notify实现生产者消费者，但是存在问题，如果生产者生产过快，消费者消费过慢，会导致生产者一直等待;它只允许一个生产者和一个消费者交替执行
public class T13 {
    private boolean flag = false;

    public synchronized void producer() {
        while (flag) {
            try {
                wait(); // 如果 flag 为 true，生产者等待
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt(); // 重新设置中断状态
                throw new RuntimeException(e);
            }
        }

        // 生产产品的代码
        System.out.println("生产者生产了一个产品。");

        flag = true; // 设置 flag 表示产品已经生产
        notifyAll(); // 通知所有等待的线程，可能有多个消费者或其他生产者
    }

    public synchronized void consumer() {
        while (!flag) {
            try {
                wait(); // 如果 flag 为 false，消费者等待
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt(); // 重新设置中断状态
                throw new RuntimeException(e);
            }
        }

        // 消费产品的代码
        System.out.println("消费者消费了一个产品。");

        flag = false; // 设置 flag 表示产品已经被消费
        notifyAll(); // 通知所有等待的线程，可能有多个生产者或其他消费者
    }

    public static void main(String[] args) {
        T13 warehouse = new T13();

        Thread producer = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                warehouse.producer();
            }
        });

        Thread consumer = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                warehouse.consumer();
            }
        });

        producer.start();
        consumer.start();
    }

}
